import { app, shell, BrowserWindow, ipcMain, screen } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'
import { Server } from 'ws'
import fs from 'fs'
import crypto from 'crypto'
import { sometestfunc } from './other.js'

let mainWindow
let app8ble2use = false
let showTempBT = false
let trialDaysLeft = 0
// 创建websocket服务器
function createWebsocketServer() {
  const wss = new Server({ port: 8002 })
  wss.on('connection', (ws) => {
    console.log('Websocket server created')
    ipcMain.on('bar_chart_click', (event, params) => {
      ws.send(JSON.stringify(params))
    })
    // ws.send(JSON.stringify({ msg: 'ok' }))
    ws.on('message', (message, isBinary) => {
      console.log('WebSocket from server', JSON.parse(message))
      wss.clients.forEach(function each(client) {
        try {
          client.send(message, { binary: isBinary })
        } catch (error) {
          console.error('Error sending message to client:', error)
        }
      })
    })
  })
}
function createWindow() {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: screen.getPrimaryDisplay().size.width,
    height: screen.getPrimaryDisplay().size.height,
    show: false,
    frame: true,
    // fullscreen: true,
    autoHideMenuBar: true,
    ...(process.platform === 'linux' ? { icon } : {}),
    webPreferences: {
      preload: join(__dirname, '../preload/index.js'),
      sandbox: false
    }
  })

  mainWindow.on('ready-to-show', () => {
    mainWindow.show()
  })

  mainWindow.webContents.setWindowOpenHandler((details) => {
    shell.openExternal(details.url)
    return { action: 'deny' }
  })

  // HMR for renderer base on electron-vite cli.
  // Load the remote URL for development or the local html file for production.
  if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
    mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
  } else {
    mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
  }
  mainWindow.maximize()
}

function createDataServer() {
  const sqlite3 = require('sqlite3').verbose()
  const db_patn = join(__dirname, '../../resources/db_statics.sqlite3')
  const sqlite3_db = new sqlite3.Database(db_patn)

  const cors = require('cors')
  const express = require('express')
  const app_express = express()
  // const http = require('http').createServer(app_express);
  let data_port = 8080

  // 允许跨域
  app_express.use(cors())
  // app_express.use(function (req, res, next) {
  //   res.header('Access-Control-Allow-Origin','*')
  //   res.header('Access-Control-Allow-Headers','Content-Type')
  //   res.header('Access-Control-Allow-Methods','GET,POST,PUT,DELETE,OPTIONS')
  //   if (req.method == 'OPTIONS') res.sendStatus(200)
  //   else next()
  // })

  app_express.get('/', (req, res) => {
    res.send('ok')
  })
  app_express.get('/list', (req, res) => {
    sqlite3_db.all('SELECT * FROM china_gdp_10years', [], (err, rows) => {
      if (err) res.send(err)
      else res.send(rows)
    })
  })
  app_express.get('/getyeardata', (req, res) => {
    sqlite3_db.all(
      'SELECT * FROM china_gdp_10years where year=?',
      [req.query.name],
      (err, rows) => {
        if (err) res.send(err)
        else res.send(rows)
      }
    )
  })
  // const dbRouter = require(join(__dirname, '../'))
  // app_express.use('/db', require(join(__dirname, './router/db_router')))

  app_express.listen(data_port, () => {
    console.log(`Data server running at: http://localhost:${data_port}`)
  })
}
// 判断App是否过期
const config_file = join(__dirname, '../../resources/cfg.json')
const usedcodes_file = join(__dirname, '../../resources/usedrcodes.json')
// AES 解密
function decryptString(encryptedText, secretKey) {
  const [ivHex, encrypted] = encryptedText.split(':')
  const iv = Buffer.from(ivHex, 'hex')
  const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(secretKey), iv)
  let decrypted = decipher.update(encrypted, 'hex', 'utf8')
  decrypted += decipher.final('utf8')
  return decrypted
}
// 处理注册码
function verifyRegCode(regcode) {
  const secretKey = 'yilongchen1yilongchen2yilongchen' //用于HMAC的密钥
  const [payloadaes, hash] = regcode.split('--')
  const payload = decryptString(payloadaes, secretKey)
  const [userId, durationInDays, timestamp] = payload.split('*')

  // 重新生成HMAC并比较
  const expectHash = crypto.createHmac('sha256', secretKey).update(payload).digest('hex')
  if (hash !== expectHash) {
    mainWindow.webContents.send('update-regstatus', { valid: false, message: '无效的注册码' })
    return { valid: false, message: '无效的注册码' }
  }
  const now = Date.now()
  if (now - timestamp > 24 * 60 * 60 * 1000) {
    mainWindow.webContents.send('update-regstatus', { valid: false, message: '注册码已过期' })
    return { valid: false, message: '注册码已过期' }
  }
  // 检查注册码是否已被使用
  let usedCodes = []
  try {
    const data = fs.readFileSync(usedcodes_file, 'utf8')
    usedCodes = JSON.parse(data)
  } catch (error) {
    console.error('无法读取文件:', error)
  }
  if (usedCodes.includes(regcode)) {
    mainWindow.webContents.send('update-regstatus', { valid: false, message: '注册码已被使用' })
    return { valid: false, message: '注册码已被使用' }
  }
  // 更新已使用的注册码列表
  usedCodes.push(regcode)
  extendTrialPeriod(durationInDays)
  fs.writeFileSync(usedcodes_file, JSON.stringify(usedCodes, null, 2), 'utf8')
  return { valid: true, userId, durationInDays }
}

// 更新使用期限
function extendTrialPeriod(durationInDays) {
  let app_configs = {}
  const now = new Date()
  try {
    const data = fs.readFileSync(config_file, 'utf8')
    app_configs = JSON.parse(data)
  } catch (error) {
    console.error('无法读取文件:', error)
  }
  const currentEndDateStr = app_configs['trialEndDate']
  let currentEndDate =
    currentEndDateStr && new Date(currentEndDateStr) > now ? new Date(currentEndDateStr) : now
  let newendDate = new Date(currentEndDate)
  console.log('old end date: ', newendDate)
  newendDate.setDate(currentEndDate.getDate() + parseInt(durationInDays))
  console.log('new end date: ', newendDate)
  // 将结束日期存储到json文件
  app_configs['trialEndDate'] = newendDate
  app_configs['regDate'] = now
  fs.writeFileSync(config_file, JSON.stringify(app_configs, null, 2), 'utf8')
}
// 计算差几天
function getDaysDiff(expire, now) {
  const timeDiff = expire.getTime() - now.getTime()
  const daysDiff = timeDiff / (24 * 60 * 60 * 1000)
  return daysDiff
}
function ifOutOfDate() {
  let configs = {}
  const now = new Date()
  try {
    let data = fs.readFileSync(config_file, 'utf8')
    configs = JSON.parse(data)
  } catch (error) {
    console.error('无法读取文件:', error)
  }
  const currentEndDateStr = configs['trialEndDate']
  
  if (currentEndDateStr && new Date(currentEndDateStr) > now) {
    let daysLeft = getDaysDiff(new Date(currentEndDateStr), now)
    trialDaysLeft = Math.ceil(daysLeft)
    if (daysLeft > 5) {
      app8ble2use = true
      showTempBT = true
      console.log('App is in use')
    } else {
      app8ble2use = false
      showTempBT = true
      console.log('App will expire in ' + trialDaysLeft + ' days')
    }
  } else {
    app8ble2use = false
    showTempBT = false
    console.log('App is out of date')
  }
  mainWindow.webContents.send('show-normal', {
    message: 'show common page',
    showui: app8ble2use,
    showTempBT: showTempBT,
    trialDaysLeft: trialDaysLeft
  })
}
// 更新App的到期日
function updateAppExpiration(regcode) {
  console.log(regcode)
  verifyRegCode(regcode)
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
  // Set app user model id for windows
  electronApp.setAppUserModelId('com.electron')
  sometestfunc()
  // Default open or close DevTools by F12 in development
  // and ignore CommandOrControl + R in production.
  // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })

  ipcMain.on('renderer-ready', () => {
    ifOutOfDate()
  })
  ipcMain.on('renderer-register', (event, data) => {
    if (!data) {
      mainWindow.webContents.send('update-regstatus', { valid: false, message: '请输入注册码' })
      return
    }
    updateAppExpiration(data)
    ifOutOfDate()
  })

  createWindow()

  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
  createDataServer()
  createWebsocketServer()
})

// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

// In this file you can include the rest of your app"s specific main process
// code. You can also put them in separate files and require them here.
